package com.ruoyi.system.service.impl;

import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.ProcessCheck;
import com.ruoyi.system.domain.ProcessCheckHistoryinfo;
import com.ruoyi.system.domain.bo.ProcessCheckBo;
import com.ruoyi.system.domain.bo.ProcessCheckHistoryinfoBo;
import com.ruoyi.system.domain.vo.ProcessCheckHistoryinfoVo;
import com.ruoyi.system.mapper.ProcessCheckHistoryinfoMapper;
import com.ruoyi.system.mapper.ProcessCheckMapper;
import com.ruoyi.system.service.IProcessCheckHistoryinfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 流程审核-历史记录Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-10
 */
@RequiredArgsConstructor
@Service
public class ProcessCheckHistoryinfoServiceImpl implements IProcessCheckHistoryinfoService {
    @Autowired
    ProcessCheckHistoryinfoMapper baseMapper;
    @Autowired
    ProcessCheckMapper checkMapper;



    /**
     * 批量创建流程审核-历史记录
     * todo 抄送
     * @param bo
     */
    @Override
    public Boolean createProcessCheckHistoryinfo(ProcessCheckBo bo) {
        ArrayList<ProcessCheckHistoryinfo> list = new ArrayList<>();
        for (Integer checkPeopleId : bo.getCheckPeopleIds()) {
            ProcessCheckHistoryinfo historyInfo = createHistoryInfo(bo, checkPeopleId);
            historyInfo.setProcessStage("0");
            validEntityBeforeSave(historyInfo);
            list.add(historyInfo);
        }
        if (list.size() > 0) {
            boolean b = baseMapper.insertBatch(list)>0;
            return b;
        }

        return false;
    }

    /**
     * 继续审核-历史记录
     *
     * @param bo
     */
    @Override
    public Boolean keepProcessCheckHistoryinfo(ProcessCheckHistoryinfoBo bo) {
        //通过审核并改变终结点标识
        Boolean aBoolean = sucessAccept(bo);
        //创建历史记录
        ProcessCheckBo bo1 = new ProcessCheckBo();
        bo1.setId(bo.getCheckId());
        bo1.setStage("2");
        Boolean processCheckHistoryinfo = createProcessCheckHistoryinfo(bo1);
        return aBoolean && processCheckHistoryinfo;
    }

    /**
     * 转为流程审核-历史记录
     * @param bo
     * @param checkPeopleId
     */
    private static ProcessCheckHistoryinfo createHistoryInfo(ProcessCheckBo bo, Integer checkPeopleId) {
        ProcessCheckHistoryinfo processCheckHistoryinfo = new ProcessCheckHistoryinfo();
        processCheckHistoryinfo.setCheckId(bo.getId());
        processCheckHistoryinfo.setState("0");
        processCheckHistoryinfo.setProcessStage(bo.getStage());
        processCheckHistoryinfo.setSubjectOfficer(Long.valueOf(checkPeopleId));
        processCheckHistoryinfo.setIsFinal("1");
        //processCheckHistoryinfo.setCopyFor(bo.getCopyFor());
        processCheckHistoryinfo.setCreateBy(bo.getCreateBy());
        processCheckHistoryinfo.setCreateTime(new Date());
        processCheckHistoryinfo.setUpdateBy(bo.getCreateBy());
        processCheckHistoryinfo.setUpdateTime(new Date());
        return processCheckHistoryinfo;
    }

    /**
     * 查询流程审核-历史记录
     */
    @Override
    public ProcessCheckHistoryinfoVo queryById(Long id){
        ProcessCheckHistoryinfo processCheckHistoryinfo = baseMapper.selectProcessCheckHistoryinfoById(id);
        return ProcessCheckHistoryinfoVo.build(processCheckHistoryinfo);
    }

    /**
     * 查询流程审核-历史记录列表
     */
    @Override
    public TableDataInfo queryPageList(ProcessCheckHistoryinfoBo bo) {
      /*  LambdaQueryWrapper<ProcessCheckHistoryinfo> lqw = buildQueryWrapper(bo);
        Page<ProcessCheckHistoryinfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);*/
        return null;
    }

    /**
     * 查询流程审核-历史记录列表
     */
    @Override
    public List<ProcessCheckHistoryinfoVo> queryList(ProcessCheckHistoryinfoBo bo) {
       /* LambdaQueryWrapper<ProcessCheckHistoryinfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);*/
        return null;

    }

/*
    private LambdaQueryWrapper<ProcessCheckHistoryinfo> buildQueryWrapper(ProcessCheckHistoryinfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ProcessCheckHistoryinfo> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getCheckId() != null, ProcessCheckHistoryinfo::getCheckId, bo.getCheckId());
        lqw.eq(StringUtils.isNotBlank(bo.getState()), ProcessCheckHistoryinfo::getState, bo.getState());
        lqw.eq(StringUtils.isNotBlank(bo.getProcessStage()), ProcessCheckHistoryinfo::getProcessStage, bo.getProcessStage());
        lqw.eq(bo.getSubjectOfficer()!=null, ProcessCheckHistoryinfo::getSubjectOfficer, bo.getSubjectOfficer());
        lqw.eq(StringUtils.isNotBlank(bo.getIsFinal()), ProcessCheckHistoryinfo::getIsFinal, bo.getIsFinal());
        lqw.eq(StringUtils.isNotBlank(bo.getCheckOpinion()), ProcessCheckHistoryinfo::getCheckOpinion, bo.getCheckOpinion());
        lqw.eq(bo.getCopyFor()!=null, ProcessCheckHistoryinfo::getCopyFor, bo.getCopyFor());
        return lqw;
    }
*/

    /**
     * 新增流程审核-历史记录
     */
    @Override
    public Boolean insertByBo(ProcessCheckHistoryinfoBo bo) {
        ProcessCheckHistoryinfo add = new ProcessCheckHistoryinfo();
        BeanUtils.copyProperties(bo, add);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insertProcessCheckHistoryinfo(add)>0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改流程审核-历史记录
     */
    @Override
    public Boolean updateByBo(ProcessCheckHistoryinfoBo bo) {
        ProcessCheckHistoryinfo update = new ProcessCheckHistoryinfo();
        BeanUtils.copyProperties(bo, ProcessCheckHistoryinfo.class);
        validEntityBeforeSave(update);
        return baseMapper.updateProcessCheckHistoryinfo(update)>0 ;
    }


    /**
     * 审核通过
     *
     * @param id
     * @param state
     * @return
     */
    public Boolean editProcessCheckState(Long id, String state) {
        ProcessCheck processCheck = checkMapper.selectProcessCheckById(id);
        processCheck.setState(state);
        return checkMapper.updateProcessCheck(processCheck) == 1 ;
    }

    /**
     * 修改流程审核-审核通过
     *
     * @param bo
     */

    public Boolean sucessAccept2(ProcessCheckHistoryinfoBo bo) {
        List<Integer> keepCheckIds = bo.getKeepCheckId();
        //是否为继续审核单据
        boolean keep = false;
        //如果有继续审核人员则为继续审核
        if (keepCheckIds.size()>0){keep = true;}
        if (!keep && bo.getState().equals("1")){
                return this.passAndNotKeep(bo);
             }
        if (keep && bo.getState().equals("1")){
            //todo 审核通过 且 是继续审核单//
            return this.passAndKeep(bo);
             }
        if ( !bo.getState().equals("1")){
            //todo 审核驳回
             }






        ProcessCheckHistoryinfo processCheckHistoryinfo = baseMapper.selectProcessCheckHistoryinfoById(bo.getId());
        processCheckHistoryinfo.setState("1");
        processCheckHistoryinfo.setCheckOpinion(bo.getCheckOpinion());
        //继续审核
        if (bo.getState().equals("2")){
            processCheckHistoryinfo.setIsFinal("0");
            if (bo.getKeepCheckId().size()>0){
                processCheckHistoryinfo.setKeepCheckId(StringUtils.join(bo.getKeepCheckId(), ","));
            }
        }
        validEntityBeforeSave(processCheckHistoryinfo);

        //1审都通过了
        if (allStage1CheckIsSuccess(bo.getCheckId())){
            //查询需要创建2审的数据
           /* LambdaQueryWrapper<ProcessCheckHistoryinfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProcessCheckHistoryinfo::getCheckId,bo.getCheckId());
            wrapper.eq(ProcessCheckHistoryinfo::getProcessStage,"1");
            wrapper.eq(ProcessCheckHistoryinfo::getIsFinal,"0");*/

            ProcessCheckHistoryinfo query = new ProcessCheckHistoryinfo();
            query.setCheckId(bo.getCheckId());
            query.setProcessStage("1");
            query.setIsFinal("0");

            List<ProcessCheckHistoryinfo> infoList = baseMapper.selectProcessCheckHistoryinfoList(query);
            //2审人id集合
            HashSet<String> hashSet = new HashSet<>();
            for (ProcessCheckHistoryinfo historyinfo : infoList) {
                String keepCheckId = historyinfo.getKeepCheckId();
                String[] split = keepCheckId.split(",");
                hashSet.addAll(Arrays.asList(split));
            }
            if (hashSet.size()>0){
                //创建2审数据
                ArrayList<ProcessCheckHistoryinfo> list = new ArrayList<>();
                for (String checkPeopleId : hashSet) {
                    ProcessCheckHistoryinfo newInfo = new ProcessCheckHistoryinfo();
                    newInfo.setCheckId(bo.getCheckId());
                    newInfo.setState("2");
                    newInfo.setProcessStage("2");
                    newInfo.setSubjectOfficer(Long.valueOf(checkPeopleId));
                    newInfo.setIsFinal("1");
                    newInfo.setCopyFor(StringUtils.join(bo.getCopyFor(),","));
                    ArrayList<String> initiators = new ArrayList<String>();
                    for (ProcessCheckHistoryinfo historyinfo : infoList) {
                        String keepCheckId = historyinfo.getKeepCheckId();
                        if (keepCheckId.contains(checkPeopleId)){
                            initiators.add(historyinfo.getCreateBy());
                        }
                    }
                    newInfo.setInitiator(StringUtils.join(initiators,","));
                    list.add(newInfo);
                }
                baseMapper.insertBatch(list);
            }
        }
        //若审核都是完成且通过状态
        if(allCheckIsSuccess(bo.getCheckId())){
            this.editProcessCheckState(bo.getCheckId(),"1");
        }

        return baseMapper.updateProcessCheckHistoryinfo(processCheckHistoryinfo)>0;


    }

    /**
     * 审核通过且继续审核
     * @param bo
     * @return
     */
    private Boolean passAndKeep(ProcessCheckHistoryinfoBo bo) {
        return null;
    }

    /**
     * 审核通过且不是继续审核
     * @param bo
     * @return
     */
    private Boolean passAndNotKeep(ProcessCheckHistoryinfoBo bo) {
        //查询本单据信息
        ProcessCheckHistoryinfo hisInfo = baseMapper.selectProcessCheckHistoryinfoById(bo.getId());
        //修改本单据状态 state==》1
        hisInfo.setState("1");
        hisInfo.setCheckOpinion(bo.getCheckOpinion());
        baseMapper.updateProcessCheckHistoryinfo(hisInfo);
        
        //查询本单据所属流程的全部信息
        ProcessCheckHistoryinfo q_hisInfo = new ProcessCheckHistoryinfo();
        q_hisInfo.setCheckId(hisInfo.getCheckId());
        List<ProcessCheckHistoryinfo> hisInfos = baseMapper.selectProcessCheckHistoryinfoList(q_hisInfo);
        String allHisCheckIsPassed = allHisCheckIsPassed(hisInfos);

        //查询check表单的单据
        ProcessCheck processCheck = checkMapper.selectProcessCheckById(hisInfo.getCheckId());
        //情况1：存在驳回单据 或待审核单据
        if(allHisCheckIsPassed.equals("0")){
            processCheck.setState("0");
            checkMapper.insertProcessCheck(processCheck);
        }else if (allHisCheckIsPassed.equals("1"))
        //情况2：全部通过
        {
            List<ProcessCheckHistoryinfo> notFinalList = allHisCheckIsFinal(hisInfos);
            //1.都是终结点
            if(notFinalList.size() == 0){
                processCheck.setState("1");
                checkMapper.insertProcessCheck(processCheck);
            }else{
                //2.不是终结点 其他节点继续审核
                //创建单据
                createNextCheckhis(notFinalList);
            }
        }
        //情况3 ： 存在待审核单据 则 之改改变词数据信息即可


        return true;
    }

    /**
     * 创建下一个审核单据
     * @param notFinalList
     */
    private void createNextCheckhis(List<ProcessCheckHistoryinfo> notFinalList) {
        //继续审核的人的id
        HashSet<Long> hashSet = new HashSet<>();
        for (ProcessCheckHistoryinfo historyinfo : notFinalList) {
            String[] split = historyinfo.getKeepCheckId().split(",");
            List<String> keepCheckIds = Arrays.asList(split);
            for (String id : keepCheckIds) {
                hashSet.add(Long.parseLong(id));
            }
        }
        ArrayList<ProcessCheckHistoryinfo> list = new ArrayList<>();
        for (ProcessCheckHistoryinfo historyinfo : notFinalList) {
            for (Long id : hashSet) {
                if (historyinfo.getKeepCheckId().contains(id.toString())){
                    ProcessCheckHistoryinfo newInfo = new ProcessCheckHistoryinfo();
                    newInfo.setCheckId(historyinfo.getCheckId());
                    newInfo.setState("2");
                    newInfo.setSubjectOfficer(id);
                    newInfo.setIsFinal("1");
                    //newInfo.setInitiator();
                    list.add(newInfo);
                }
            }
        }
        for (ProcessCheckHistoryinfo historyinfo : list) {
            ArrayList<String> inits = new ArrayList<>();
            for (ProcessCheckHistoryinfo oldInfo : notFinalList) {
                if (oldInfo.getKeepCheckId().contains(historyinfo.getSubjectOfficer().toString())){
                    inits.add(oldInfo.getCreateBy());
                }
            }
            historyinfo.setInitiator(StringUtils.join(inits,","));
        }
        baseMapper.insertBatch(list);
    }

    /**
     * 返回非终结点单据列表
     * @param hisInfos
     * @return
     */
    public List<ProcessCheckHistoryinfo> allHisCheckIsFinal(List<ProcessCheckHistoryinfo> hisInfos) {
        ArrayList<ProcessCheckHistoryinfo> list = new ArrayList<>();
        for (ProcessCheckHistoryinfo hisInfo : hisInfos) {
            if (!hisInfo.getIsFinal().equals("1")) {
                list.add(hisInfo);
            }
        }
        return list;


    }

    public Boolean sucessAccept(ProcessCheckHistoryinfoBo bo) {
        ProcessCheckHistoryinfo processCheckHistoryinfo = baseMapper.selectProcessCheckHistoryinfoById(bo.getId());
        processCheckHistoryinfo.setState("1");
        processCheckHistoryinfo.setCheckOpinion(bo.getCheckOpinion());
        //继续审核
        if (bo.getState().equals("2")){
            processCheckHistoryinfo.setIsFinal("0");
            if (bo.getKeepCheckId().size()>0){
                processCheckHistoryinfo.setKeepCheckId(StringUtils.join(bo.getKeepCheckId(), ","));
            }
        }
        validEntityBeforeSave(processCheckHistoryinfo);

        //1审都通过了
        if (allStage1CheckIsSuccess(bo.getCheckId())){
            //查询需要创建2审的数据
           /* LambdaQueryWrapper<ProcessCheckHistoryinfo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ProcessCheckHistoryinfo::getCheckId,bo.getCheckId());
            wrapper.eq(ProcessCheckHistoryinfo::getProcessStage,"1");
            wrapper.eq(ProcessCheckHistoryinfo::getIsFinal,"0");*/

            ProcessCheckHistoryinfo query = new ProcessCheckHistoryinfo();
            query.setCheckId(bo.getCheckId());
            query.setProcessStage("1");
            query.setIsFinal("0");

            List<ProcessCheckHistoryinfo> infoList = baseMapper.selectProcessCheckHistoryinfoList(query);
            //2审人id集合
            HashSet<String> hashSet = new HashSet<>();
            for (ProcessCheckHistoryinfo historyinfo : infoList) {
                String keepCheckId = historyinfo.getKeepCheckId();
                String[] split = keepCheckId.split(",");
                hashSet.addAll(Arrays.asList(split));
            }
            if (hashSet.size()>0){
                //创建2审数据
                ArrayList<ProcessCheckHistoryinfo> list = new ArrayList<>();
                for (String checkPeopleId : hashSet) {
                    ProcessCheckHistoryinfo newInfo = new ProcessCheckHistoryinfo();
                    newInfo.setCheckId(bo.getCheckId());
                    newInfo.setState("2");
                    newInfo.setProcessStage("2");
                    newInfo.setSubjectOfficer(Long.valueOf(checkPeopleId));
                    newInfo.setIsFinal("1");
                    newInfo.setCopyFor(StringUtils.join(bo.getCopyFor(),","));
                    ArrayList<String> initiators = new ArrayList<String>();
                    for (ProcessCheckHistoryinfo historyinfo : infoList) {
                        String keepCheckId = historyinfo.getKeepCheckId();
                        if (keepCheckId.contains(checkPeopleId)){
                            initiators.add(historyinfo.getCreateBy());
                        }
                    }
                    newInfo.setInitiator(StringUtils.join(initiators,","));
                    list.add(newInfo);
                }
                baseMapper.insertBatch(list);
            }
        }
        //若审核都是完成且通过状态
        if(allCheckIsSuccess(bo.getCheckId())){
            this.editProcessCheckState(bo.getCheckId(),"1");
        }

        return baseMapper.updateProcessCheckHistoryinfo(processCheckHistoryinfo)>0;


    }

    /**
     * 根据（通过/驳回/继续审核 来决定要进行那些操作）
     *
     * @param bo
     * @return
     */
    @Override
    public Boolean editAcceptState(ProcessCheckHistoryinfoBo bo) {
        if(bo.getState().equals("1")){
            return sucessAccept(bo);
        }else if(bo.getState().equals("0")){
            return failAccept(bo);
        }else if(bo.getState().equals("2")){
            return keepProcessCheckHistoryinfo(bo);
        }
        return false;
    }

    /**
     * 修改流程审核-审核驳回
     *
     * @param bo
     */
    @Override
    public Boolean failAccept(ProcessCheckHistoryinfoBo bo) {
        ProcessCheckHistoryinfo processCheckHistoryinfo = baseMapper.selectProcessCheckHistoryinfoById(bo.getId());
        processCheckHistoryinfo.setState("0");
        processCheckHistoryinfo.setCheckOpinion(bo.getCheckOpinion());
        validEntityBeforeSave(processCheckHistoryinfo);

       //审核驳回
        this.editProcessCheckState(bo.getCheckId(),"0");


        return baseMapper.updateProcessCheckHistoryinfo(processCheckHistoryinfo) > 0;


    }

    /**
     * 根据审核id判断是否所有审核都是完成且通过状态
     * @param checkId
     * @return
     */
    public Boolean allCheckIsSuccess(Long checkId) {
    /*    LambdaQueryWrapper<ProcessCheckHistoryinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProcessCheckHistoryinfo::getIsFinal, "1");
        wrapper.eq(ProcessCheckHistoryinfo::getCheckId, checkId);*/
        ProcessCheckHistoryinfo query = new ProcessCheckHistoryinfo();
        query.setCheckId(checkId);
        query.setIsFinal("1");
        for (ProcessCheckHistoryinfo processCheckHistoryinfo : baseMapper.selectProcessCheckHistoryinfoList(query)) {
            if (processCheckHistoryinfo.getState().equals("0")) {
             return false;
            }
        }
        return true;


    }


    /**
     * 根据审核id判断是否所有一审核都是完成且通过状态
     * @param checkId
     * @return
     */
    public Boolean allStage1CheckIsSuccess(Long checkId) {
       /* LambdaQueryWrapper<ProcessCheckHistoryinfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ProcessCheckHistoryinfo::getProcessStage, "1");
        wrapper.eq(ProcessCheckHistoryinfo::getCheckId, checkId);*/
        ProcessCheckHistoryinfo query = new ProcessCheckHistoryinfo();
        query.setCheckId(checkId);
        query.setProcessStage( "1");
        for (ProcessCheckHistoryinfo processCheckHistoryinfo : baseMapper.selectProcessCheckHistoryinfoList(query)) {
            if (processCheckHistoryinfo.getState().equals("0")) {
                return false;
            }
        }

        HashSet<String> hashSet = new HashSet<>();
        for (ProcessCheckHistoryinfo processCheckHistoryinfo : baseMapper.selectProcessCheckHistoryinfoList(query)) {
            hashSet.add(processCheckHistoryinfo.getSubjectOfficer().toString());
        }
        if (hashSet.size()>0) {
            for (String id : hashSet) {
                Long longId = Long.valueOf(id);


            }
        }

        return true;


    }


    /**
     * 所有单据都是审核通过状态
     * @param hisInfos
     * @return
     */
    public String allHisCheckIsPassed(List<ProcessCheckHistoryinfo> hisInfos) {

        for (ProcessCheckHistoryinfo hisInfo : hisInfos) {
            if (hisInfo.getState().equals("0")) {
                return "0";
            }
        }
        for (ProcessCheckHistoryinfo hisInfo : hisInfos) {
            if (hisInfo.getState().equals("2")) {
                return "2";
            }
        }
        return "1";


    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ProcessCheckHistoryinfo entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除流程审核-历史记录
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        //return baseMapper.deleteBatchIds(ids) > 0;
        return null;
    }
}
